import { type VariableUpdateListeners, evaluateExpression } from "./evaluate-expression";
//VariableUpdateListeners 是用于存储变量变更监听器的类型。
//evaluateExpression 是负责解析并计算表达式的函数

//这是一个 TypeScript 文件，其主要功能是根据输入的 LaTeX 表达式计算结果，并动态更新页面上的结果显示（例如公式计算后的数值）。它还支持变量监听机制，当相关变量发生变化时自动重新计算并刷新结果。

//latex: 输入的 LaTeX 公式字符串。
// id: 唯一标识符，用于关联此计算上下文。
// resultSpan: DOM 元素，用于显示计算结果。
// showEvalResult: 布尔值，控制是否显示结果。
// editorStorage: 存储变量和监听器的对象。
export function updateEvaluation(latex: string, id: string, resultSpan: HTMLSpanElement, showEvalResult: boolean, editorStorage: any) {
  let evalRes = evaluateExpression(  //调用 evaluateExpression 函数对输入的 latex 表达式进行求值。
    latex,
    editorStorage.variables,
    editorStorage.variableListeners
  ); // Do not show if error occurs (in general, we probably want to make showing the result optional)
  //定义一个局部函数 updateResultSpan，用于更新 resultSpan 的显示内容。
  const updateResultSpan = () => {
    if (evalRes?.result) {
      if (evalRes.result.toString().split(".")[1]?.length > 5) {
        resultSpan.innerText = "=" + evalRes.result.toFixed(4);
      } else {
        resultSpan.innerText = "=" + evalRes.result.toString();
      }
    } else {
      resultSpan.innerText = "=Error";
    }

    if (!showEvalResult) {
      resultSpan.style.display = "none";
    } else {
      resultSpan.style.display = "inline-block";
    }
  };
  updateResultSpan();  //立即调用一次 updateResultSpan，初始化结果显示。
  if (evalRes?.variablesUsed) {  ///监听变量更新
    for (const v of evalRes.variablesUsed) {
      // Register Listeners
      let listenersForV: VariableUpdateListeners = editorStorage.variableListeners[v];
      if (listenersForV == undefined) {
        listenersForV = [];
      }
      listenersForV.push({
        id: id,
        onUpdate: () => {
          {
            evalRes = evaluateExpression(
              latex,
              editorStorage.variables,
              editorStorage.variableListeners
            );
            updateResultSpan();
          }
        },
      });
      editorStorage.variableListeners[v] = listenersForV;
    }
  }
  return evalRes;
}
